import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.JOptionPane;

import org.rsbot.bot.Bot;
import org.rsbot.event.events.ServerMessageEvent;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.ServerMessageListener;
import org.rsbot.script.Constants;
import org.rsbot.script.Methods;
import org.rsbot.script.Script;
import org.rsbot.script.ScriptManifest;
import org.rsbot.script.wrappers.RSCharacter;
import org.rsbot.script.wrappers.RSInterface;
import org.rsbot.script.wrappers.RSInterfaceChild;
import org.rsbot.script.wrappers.RSInterfaceComponent;
import org.rsbot.script.wrappers.RSItem;
import org.rsbot.script.wrappers.RSItemTile;
import org.rsbot.script.wrappers.RSNPC;
import org.rsbot.script.wrappers.RSObject;
import org.rsbot.script.wrappers.RSTile;

@ScriptManifest(authors = { "Mouchicc" }, category = "Combat", name = "MDrags", version = 2.2)
public class MDrags extends Script implements PaintListener,
		ServerMessageListener {

	int startLvl;
	int stat;
	int fightMode;
	int spell;
	int[] dragIDs;
	String skill;
	String style;
	int eatAT;
	int chosenSpellForUse;

	public int[] charms = { 12158, 12159, 12160, 12163 };
	public int ITPID = 0000;
	int tehArrows;
	public boolean doingspec;
	public boolean potion;
	public boolean charmpickup;
	public boolean takeSomeItem;
	public boolean ranging;
	int randomWield = random(70, 120);
	int CurSTAT;
	int RealSTAT;
	public static int[] potID;

	boolean drinkAFire = false;

	RSNPC dragon;

	long thisTime = System.currentTimeMillis();
	long antiBTime = System.currentTimeMillis() + random(250000, 50000);

	long startTime = System.currentTimeMillis();
	int startExp;
	int killed = -1;

	int anim;
	int anim4;
	String combat;
	String item;
	String action;
	String status;
	long time;

	int[] profitItems = new int[] { 1149, 4087, 4585, 11286 };

	int[] items;
	RSItemTile tile;
	RSObject obj = null;
	String itemName;

	public int[] alchIt = new int[] { 1249, 2366, 137, 1201, 1215, 1919, 1127,
			1185, 1147, 1540 };
	public int[] alchItems = new int[] {};
	public static int[] FoodID = { 1895, 1893, 1891, 4293, 2142, 291, 2140,
			3228, 9980, 7223, 6297, 6293, 6295, 6299, 7521, 9988, 7228, 2878,
			7568, 2343, 1861, 13433, 315, 325, 319, 3144, 347, 355, 333, 339,
			351, 329, 3381, 361, 379, 380, 10136, 5003, 379, 365, 373, 374,
			7946, 385, 397, 391, 3369, 3371, 3373, 2309, 2325, 2333, 2327,
			2331, 2323, 2335, 7178, 7180, 7188, 7190, 7198, 7200, 7208, 7210,
			7218, 7220, 2003, 2011, 2289, 2291, 2293, 2295, 2297, 2299, 2301,
			2303, 1891, 1893, 1895, 1897, 1898, 1899, 1900, 1901, 1902, 7072,
			7062, 7078, 7064, 7084, 7082, 7066, 7068, 1942, 6701, 6703, 7054,
			6705, 7056, 7060, 2130, 1985, 1993, 1989, 1978, 5763, 5765, 1913,
			5747, 1905, 5739, 1909, 5743, 1907, 1911, 5745, 2955, 5749, 5751,
			5753, 5755, 5757, 5759, 5761, 2084, 2034, 2048, 2036, 2217, 2213,
			2205, 2209, 2054, 2040, 2080, 2277, 2225, 2255, 2221, 2253, 2219,
			2281, 2227, 2223, 2191, 2233, 2092, 2032, 2074, 2030, 2281, 2235,
			2064, 2028, 2187, 2185, 2229, 6883, 1971, 4608, 1883, 1885 };

	int profitHelms;
	int profitPlateLegs;
	int profitPlateSkirts;
	int profitVisages;
	int profitHelmsGE;
	int profitPlateLegsGE;
	int profitPlateSkirtsGE;
	int profitVisagesGE;

	boolean alch = false;

	int[] dragonMedHelms = new int[] { 1149, 1150, 6967, 13495 };
	int[] dragonPlateLs = new int[] { 4087, 4088, 4180, 13488 };
	int[] dragonPlateSks = new int[] { 4585, 4586 };
	int[] visages = new int[] { 11286, 11287 };

	ScriptManifest properties = getClass().getAnnotation(ScriptManifest.class);

	public double getVersion() {
		return properties.version();
	}

	public String getName() {
		return properties.name();
	}

	// What to load on Start
	@Override
	public boolean onStart(Map<String, String> args) {

		dragIDs = new int[] { 1591, 1592 };
		stat = STAT_MAGIC;
		style = "Magic";
		skill = "Magic";
		spell = Constants.SPELL_FIRE_BOLT;

		profitHelmsGE = grandExchange.loadItemInfo(1149).getMarketPrice();
		profitPlateLegsGE = grandExchange.loadItemInfo(4087).getMarketPrice();
		profitPlateSkirtsGE = grandExchange.loadItemInfo(4585).getMarketPrice();
		profitVisagesGE = grandExchange.loadItemInfo(11286).getMarketPrice();

		log("This is Version: " + getVersion());
		log("Got the GE Item prices!");

		return true;
	}

	// Method edited so it doesnt open the inventorytab always
	@Override
	public RSInterfaceChild getInventoryInterface() {
		if (getInterface(Constants.INVENTORY_COM_X).isValid()) {
			return RSInterface.getChildInterface(Constants.INVENTORY_COM_X,
					Constants.INVENTORY_COM_Y);
		}

		return RSInterface.getChildInterface(Constants.INVENTORY_X,
				Constants.INVENTORY_Y);
	}

	// Checks if there are some profit items to pick
	public boolean needToPProfit() {
		if (getGroundItemByID(11286) != null) {
			JOptionPane.showMessageDialog(null, "     !!!DRACONIC VISAGE!!!",
					"!!!WARNING!!!", JOptionPane.WARNING_MESSAGE);
		}
		for (int i = 0; i < profitItems.length; i++) {
			while ((tile = getGroundItemByID(profitItems[i])) != null) {
				if (isInventoryFull()) {
					if (inventoryContains(229)) {
						clickInventoryItem(229, "rop");
						wait(random(300, 500));
					}
					break;
				}
				items = profitItems;
				log("Its profitItems!");
				return true;
			}
		}
		return false;
	}

	// Checks if there are any charms
	public boolean needToPCharms() {
		for (int i = 0; i < charms.length; i++) {
			while ((tile = getGroundItemByID(charms[i])) != null) {
				if (isInventoryFull()) {
					if (inventoryContains(229)) {
						clickInventoryItem(229, "rop");
						wait(random(300, 500));
					}
					break;
				}
				items = charms;
				log("Its charms!");
				return true;
			}
		}
		return false;
	}

	// Method to get some corners around an npc
	public ArrayList<RSTile> getTilesAround(RSNPC npc) {
		RSTile tile = npc.getLocation();
		int x = tile.getX();
		int y = tile.getY();
		ArrayList<RSTile> result = new ArrayList<RSTile>();
		result.add(new RSTile(x, y - random(6, 8)));
		result.add(new RSTile(x, y + random(6, 8)));
		result.add(new RSTile(x - random(6, 8), y));
		result.add(new RSTile(x + random(6, 8), y));

		result.add(new RSTile(x - random(6, 8), y - random(6, 8)));
		result.add(new RSTile(x + random(6, 8), y + random(6, 8)));
		result.add(new RSTile(x + random(6, 8), y - random(6, 8)));
		result.add(new RSTile(x - random(6, 8), y + random(6, 8)));

		result.add(tile);
		return result;
	}

	public enum Action {
		PICK_CHARMS, PICK_PROFIT, DRINK_POT, FIGHT, WALK_TO_DRAG, GET_AWAY, ANTIBAN, ALCH, EAT
	};

	// getAction() method!
	public Action getAction() {
		if (getMyPlayer().isInCombat()) {
			combat = "In Combat!";

			RSCharacter some = getMyPlayer().getInteracting();
			if (some != null) {
				anim4 = some.getAnimation();
			}

			if (getInteractingNPC() != null) {
				if (getInteractingNPC().getID() == 1591) {
					dragon = getInteractingNPC();
					if (distanceTo(dragon) <= 3) {
						status = "Melee Attack Iron Drag!";
						return Action.GET_AWAY;
					}
				} else if (getInteractingNPC().getID() == 1592) {
					dragon = getInteractingNPC();
					if (distanceTo(dragon) <= 4) {
						status = "Melee Attack Steel Drag!";
						return Action.GET_AWAY;
					}
				}
			}
		}

		if (inventoryContains(561) && inventoryContains(554)) {
			if (inventoryContainsOneOf(alchIt)) {
				status = "Alch";
				return Action.ALCH;
			}
		}

		if (getMyPlayer().getHPPercent() <= random(40, 60)) {
			status = "Eat";
			return Action.EAT;
		}

		if (drinkAFire) {
			status = "Potting";
			return Action.DRINK_POT;
		}

		if (thisTime > antiBTime) {
			antiBTime = System.currentTimeMillis() + random(25000, 50000);
			status = "Antiban";
			return Action.ANTIBAN;
		}

		if (needToPProfit()) {
			status = "Profit items";
			return Action.PICK_PROFIT;
		}

		if (needToPCharms()) {
			status = "Charms";
			return Action.PICK_CHARMS;
		}

		if (!getMyPlayer().isInCombat()) {
			combat = "Not in Combat!";

			if (!needToPProfit() && !needToPCharms()) {
				dragon = getNearestFreeNPCToAttackByID(dragIDs);
				if (dragon != null && pointOnScreen(dragon.getScreenLocation())) {
					status = "Fight";
					return Action.FIGHT;
				} else if (dragon != null
						&& !pointOnScreen(dragon.getScreenLocation())) {
					status = "Walk to dragon";
					return Action.WALK_TO_DRAG;
				}
			}
		}

		status = "Antiban";
		return Action.ANTIBAN;
	}

	@Override
	public int loop() {
		if (getMyPlayer().isMoving()) {
			return random(400, 800);
		}
		getAnimation();

		if (getEnergy() >= random(50, 70)) {
			if (!isRunning()) {
				setRunning();
			}
		}

		// if (!setAttackStyle()) {
		// setAttackStyle();
		// }

		Action action = getAction();
		switch (action) {
		case ALCH:
			for (int i : alchIt) {
				RSItem item = getInventoryItemByID(i);
				if (item == null) {
					continue;
				}
				if (getCurrentTab() != TAB_MAGIC) {
					log("Open Tab Magic");
					openTab(TAB_MAGIC);
					wait(random(200, 350));
				}
				castAlchSpell();
				wait(random(400, 600));
				clickInventoryItem(i, true);
				log("clicked item");
				wait(random(1400, 1600));
				if (getCurrentTab() != TAB_INVENTORY) {
					openTab(TAB_INVENTORY);
				}
				return random(400, 500);
			}
			return random(600, 800);

		case EAT:
			if (inventoryContainsOneOf(FoodID)) {
				for (int i : FoodID) {
					RSItem item = getInventoryItemByID(i);
					if (item == null) {
						continue;
					}
					if (getCurrentTab() != TAB_INVENTORY) {
						log("Open Tab Magic");
						openTab(TAB_INVENTORY);
						wait(random(200, 350));
					}
					if (clickInventoryItem(i, true)) {
						log("Eated: " + IDtoName(i));
						return random(400, 500);
					} else {
						return random(100, 200);
					}
				}
			}
			break;

		case DRINK_POT:
			if (drinkAFire) {
				if (drinkAntiPot2()) {
					log("Drinked some AntiFire Potion");
					drinkAFire = false;
					return random(400, 600);
				} else {
					return random(100, 200);
				}
			}
			break;

		case PICK_CHARMS:
			if (items == charms) {
				if (inventoryContains(229)) {
					clickInventoryItem(229, "rop");
					wait(random(300, 500));
				}
				if (!getMyPlayer().isMoving()) {
					if (pick(charms, "charm")) {
						return random(400, 600);
					}
					while (getMyPlayer().isMoving()) {
						wait(random(20, 60));
					}
					item = "Nothing";
					return random(400, 600);
				}
			}
			break;

		case PICK_PROFIT:
			if (inventoryContains(229)) {
				clickInventoryItem(229, "rop");
				wait(random(300, 500));
			}
			if (items == profitItems) {
				if (!getMyPlayer().isMoving()) {
					for (int i : profitItems) {
						itemName = IDtoName(i);
					}
					String act = "Take " + itemName;
					if (pick(profitItems, act)) {
						return random(400, 600);
					}
					while (getMyPlayer().isMoving()) {
						wait(random(20, 60));
					}
					item = "Nothing";
					return random(400, 600);
				}
			}
			break;

		case FIGHT:
			dragon = getNearestFreeNPCToAttackByID(dragIDs);
			if (dragon != null) {
				if (getMyPlayer().getInteracting() == null) {
					if (clickNPC(dragon, "Attack")) {
						return random(400, 600);
					} else {
						return random(100, 200);
					}
				}
			}
			break;

		case WALK_TO_DRAG:
			dragon = getNearestFreeNPCToAttackByID(dragIDs);
			if (dragon != null) {
				if (getMyPlayer().getInteracting() == null) {
					ArrayList<RSTile> tilesNPC = getTilesAround(dragon);
					RSTile walk = tilesNPC.get(random(0, tilesNPC.size()));
					int i = 0;
					RSObject obj = null;
					while ((obj = getObjectAt(walk)) != null
							&& obj.getID() != -1) {
						i++;
						walk = tilesNPC.get(i);
					}
					for (RSTile tile : tilesNPC) {
						if (distanceTo(tile) < distanceTo(walk)) {
							obj = getObjectAt(tile);
							if (obj != null && obj.getID() != -1) {
								continue;
							}
							walk = tile;
						}
					}
					while (!tilesNPC.contains(getLocation())) {
						if (getMyPlayer().isMoving()) {
							wait(random(30, 60));
							continue;
						}
						WalkSmart(walk.randomizeTile(2, 2));
						log(RSTileToString(walk));
						return random(400, 600);
					}
				}
			}
			break;

		case GET_AWAY:
			if (getInteractingNPC() != null) {
				dragon = getInteractingNPC();

				ArrayList<RSTile> tilesNPC = getTilesAround(dragon);
				RSTile walk = tilesNPC.get(random(0, tilesNPC.size()));
				int i = 0;
				RSObject obj = null;
				while ((obj = getObjectAt(walk)) != null && obj.getID() != -1) {
					i++;
					walk = tilesNPC.get(i);
				}
				for (RSTile tile : tilesNPC) {
					if (distanceTo(tile) < distanceTo(walk)) {
						obj = getObjectAt(tile);
						if (obj != null && obj.getID() != -1) {
							continue;
						}
						walk = tile;
					}
				}
				while (!tilesNPC.contains(getLocation())) {
					if (getMyPlayer().isMoving()) {
						wait(random(30, 60));
						continue;
					}
					WalkSmart(walk.randomizeTile(2, 2));
					log(RSTileToString(walk));
					return random(400, 600);
				}
			}
			break;

		case ANTIBAN:
			if (inventoryContains(229)) {
				clickInventoryItem(229, "rop");
				wait(random(300, 500));
				return random(100, 200);
			} else {
				antiBan(0, 7);
			}
			break;
		}
		return random(200, 400);
	}

	public String RSTileToString(RSTile t) {
		if (t != null) {
			int x = t.getX();
			int y = t.getY();
			String s = "WalkTo: RSTile(" + x + "," + y + ")";
			return s;
		}
		return null;
	}

	// Antiban made by Zenzie
	private void antiBan(int minC, int maxC) {

		final int randomAction = random(minC, maxC);
		switch (randomAction) {
		case 0:
			break;
		case 1:
			Point randomMouse;
			final int rndMovement = random(1, 5);
			for (int a = 0; a < rndMovement; a++) {
				randomMouse = new Point(random(15, 730), random(15, 465));
				moveMouse(randomMouse);
				wait(random(50, 800));
			}
			break;
		case 2:
			final int currentAngle = getCameraAngle();
			switch (random(0, 1)) {
			case 0:
				setCameraRotation(currentAngle + random(0, 650));
				break;
			case 1:
				setCameraRotation(currentAngle - random(0, 650));
				break;
			}
		case 3:
			final int currentAlt = Bot.getClient().getCamPosZ();
			final int random = random(0, 10);
			if (random <= 7) {
				setCameraAltitude(currentAlt - random(0, 100));
				break;
			} else {
				setCameraAltitude(currentAlt + random(0, 100));
				break;
			}
		case 4:
			final int currentAngle2 = getCameraAngle();
			Bot.getClient().getCamPosZ();
			switch (random(0, 1)) {
			case 0:
				setCameraRotation(currentAngle2 + random(0, 650));
				setCameraAltitude(random(80, 100));
				break;
			case 1:
				setCameraRotation(currentAngle2 - random(0, 650));
				setCameraAltitude(random(40, 80));
				break;
			}
		case 5:
			break;

		case 6:
			final int currentAlt2 = Bot.getClient().getCamPosZ();
			final int random2 = random(0, 2);
			if (random2 <= 2) {
				setCameraAltitude(currentAlt2 - random(-100, +100));
				break;
			} else {
				setCameraAltitude(currentAlt2 + random(-100, +100));
				break;
			}

		case 7:
			if (random(1, 60) == 1) {
				openTab(TAB_STATS);
				moveMouse(random(669, 706), random(233, 260));
				wait(random(731, 2313));
				openTab(TAB_INVENTORY);
				break;
			}

		}
		return;
	}

	public boolean drinkAntiPot2() {
		int[] one = new int[] { 2459, 2458 };
		int[] two = new int[] { 2457, 2456 };
		int[] three = new int[] { 2455, 2454 };
		int[] four = new int[] { 2453, 2452 };
		int[][] all = { one, two, three, four };

		for (int[] pot : all) {
			if (inventoryContainsOneOf(pot)) {
				for (int i = 0; i < pot.length; i++) {
					if (getInventoryCount(pot[i]) >= 1) {
						if (clickInventoryItem(pot[i], "Drink")) {
							time = System.currentTimeMillis();
							return true;
						}
					}
				}
			}
		}
		return false;
	}

	// Drinks antipotion by pot count.
	public boolean drinkAntiPot() {
		int[] one = new int[] { 2459, 2458 };
		int[] two = new int[] { 2457, 2456 };
		int[] three = new int[] { 2455, 2454 };
		int[] four = new int[] { 2453, 2452 };

		if (inventoryContainsOneOf(one)) {
			for (int i = 0; i < one.length; i++) {
				if (getInventoryCount(one[i]) >= 1) {
					if (clickInventoryItem(one[i], "Drink")) {
						time = System.currentTimeMillis();
						return true;
					}
				}
			}
		} else if (inventoryContainsOneOf(two)) {
			for (int i = 0; i < two.length; i++) {
				if (getInventoryCount(two[i]) >= 1) {
					if (clickInventoryItem(two[i], "Drink")) {
						time = System.currentTimeMillis();
						return true;
					}
				}
			}
		} else if (inventoryContainsOneOf(three)) {
			for (int i = 0; i < three.length; i++) {
				if (getInventoryCount(three[i]) >= 1) {
					if (clickInventoryItem(three[i], "Drink")) {
						time = System.currentTimeMillis();
						return true;
					}
				}
			}
		} else if (inventoryContainsOneOf(four)) {
			for (int i = 0; i < four.length; i++) {
				if (getInventoryCount(four[i]) >= 1) {
					if (clickInventoryItem(four[i], "Drink")) {
						time = System.currentTimeMillis();
						return true;
					}
				}
			}
		}
		return false;
	}

	// Gets the interactingNPC
	public RSNPC getInteractingNPC() {
		final int[] validNPCs = Bot.getClient().getRSNPCIndexArray();
		final org.rsbot.accessors.RSNPC[] npcs = Bot.getClient()
				.getRSNPCArray();

		for (final int element : validNPCs) {
			if (npcs[element] == null) {
				continue;
			}
			final RSNPC Monster = new RSNPC(npcs[element]);
			if (Monster.getInteracting() != null) {
				if (Monster.getInteracting().equals(getMyPlayer())) {
					return Monster;
				}
			}
		}
		return null;
	}

	// Gets the animation of interacting NPC.
	public int getAnimation() {
		if (getInteractingNPC() != null) {
			anim = getInteractingNPC().getAnimation();
			return anim;
		}
		return anim;
	}

	// Sets the attack style you want
	public boolean setAttackStyle() {
		if (style.equals("Ranged") || style.equals("Melee")) {
			if (fightMode != getFightMode()) {
				if (getCurrentTab() != Constants.TAB_ATTACK) {
					openTab(Constants.TAB_ATTACK);
					wait(random(150, 250));
				}
				setFightMode(fightMode);
				wait(random(15, 250));
				openTab(Constants.TAB_INVENTORY);
				return true;
			}
		} else if (style.equals("Magic")) {
			if (autoCastSpell(spell)) {
				wait(random(15, 250));
				openTab(Constants.TAB_INVENTORY);
				return true;
			}
		}
		return false;
	}

	/**
	 * Activates/deactivates a prayer via interfaces. Written by Mouchicc
	 * 
	 * @param pray
	 *            The integer that represents the prayer by counting from left
	 *            to right.
	 * @param activate
	 *            <tt>true</tt> to activate; <tt>false</tt> to deactivate.
	 * @return <tt>true</tt> if the interface was clicked; otherwise
	 *         <tt>false</tt>.
	 */
	public boolean setPrayer(final int pray, boolean activate) {
		return RSInterface.getChildInterface(271, 5).getComponents()[pray]
				.getBackgroundColor() == -1
				&& atInterface(RSInterface.getChildInterface(271, 5)
						.getComponents()[pray], activate ? "Activate"
						: "Deactivate");
	}

	/**
	 * Autocasts a spell via interfaces. Written by: Mouchicc
	 * 
	 * @param spell
	 *            The spell to cast.
	 * @return <tt>true</tt> if the "Autocast" interface option was clicked;
	 *         otherwise <tt>false</tt>.
	 */
	public boolean autoCastSpell(final int spell) {
		if (getSetting(43) != 4) {
			if (getCurrentTab() != Constants.TAB_MAGIC) {
				openTab(Constants.TAB_MAGIC);
				wait(random(150, 250));
			}
			return atInterface(Constants.INTERFACE_TAB_MAGIC, spell, "Autocast");
		}
		return false;
	}

	// Sets the running
	public void setRunning() {
		char CONTROL = KeyEvent.VK_CONTROL;
		if (!isRunning() && getEnergy() > random(50, 70)) {
			Bot.getInputManager().pressKey(CONTROL);
			wait(random(200, 400));
			Bot.getInputManager().releaseKey(CONTROL);
		}
	}

	// TODO: Does Special!
	public void doSpec() {
		if (getSetting(300) >= 1000 && !((getSetting(301)) == 1)
				&& doingspec == true) {
			openTab(Constants.TAB_ATTACK);
			clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
			wait(350);
		}
		return;
	}

	// TODO: Profit gained
	public int profit() {
		int totalProfitGained = 0;
		if (getCurrentTab() == TAB_INVENTORY) {
			int profitOffAlches = getInventoryCount(995);

			profitHelms = getInventoryCount(dragonMedHelms) * profitHelmsGE;
			profitPlateLegs = getInventoryCount(dragonPlateLs)
					* profitPlateLegsGE;
			profitPlateSkirts = getInventoryCount(dragonPlateSks)
					* profitPlateSkirtsGE;
			profitVisages = getInventoryCount(visages) * profitVisagesGE;

			totalProfitGained = (profitHelms + profitPlateLegs
					+ profitPlateSkirts + profitVisages + profitOffAlches);

			return totalProfitGained;
		}
		return totalProfitGained;
	}

	public void onFinish() {
		log("Finished!");
	}

	@Override
	public void onRepaint(Graphics g) {
		// if (isLoggedIn()) {
		if (startTime == 0) {
			startTime = System.currentTimeMillis();
		}

		if (startLvl <= 0 || startExp <= 0) {
			startLvl = skills.getCurrentSkillLevel(stat);
			startExp = skills.getCurrentSkillExp(stat);
		}

		long millis = System.currentTimeMillis() - startTime;
		long hours = millis / (1000 * 60 * 60);
		millis -= hours * (1000 * 60 * 60);
		long minutes = millis / (1000 * 60);
		millis -= minutes * (1000 * 60);
		long seconds = millis / 1000;

		int xpPHour = (int) ((skills.getCurrentSkillExp(stat) - startExp) * (3600000D / (((double) System
				.currentTimeMillis() - (double) startTime))));

		int X = 4;
		int Y = 4;
		int Xl = 224;
		int Yl = 130;
		int Barl = 44;

		g.setColor(new Color(220, 0, 184, 147));
		g.fillRoundRect(X, Y, skills.getPercentToNextLevel(stat) * Xl / 100,
				Barl / 2, 3, 3);
		g.setColor(new Color(244, 0, 203, 147));
		g.fillRoundRect(X, Y,
				(skills.getPercentToNextLevel(stat) * Xl / 100) - 1,
				(Barl / 2) - 1, 3, 3);
		drawStringWithShadow((int) skills.getPercentToNextLevel(stat)
				+ " % to level", X + Xl / 2 - 30, Y + 14, g);
		g.drawRoundRect(X, Y, Xl, Barl / 2, 2, 2);
		Y += Y + Barl / 2;
		g.fillRoundRect(X, Y, Xl, Yl, 2, 2);
		g.setColor(new Color(255, 255, 255));
		g.drawRoundRect(X, Y, Xl, Yl, 2, 2);
		g.setFont(new Font("Papyrus", Font.BOLD, 11));
		g.setColor(Color.PINK);
		drawStringWithShadow(getName() + " - V" + getVersion(), X + 10,
				Y += 15, g);
		g.setColor(Color.ORANGE);
		drawStringWithShadow("Profit: " + profit(), X + 10, Y += 15, g);
		drawStringWithShadow("Running for " + hours + ":" + minutes + ":"
				+ seconds, X + 10, Y += 15, g);
		drawStringWithShadow("Current " + skill + " level : "
				+ skills.getRealSkillLevel(stat), X + 10, Y += 15, g);
		drawStringWithShadow("Gained " + skill + " levels : "
				+ (skills.getRealSkillLevel(stat) - startLvl), X + 10, Y += 15,
				g);
		drawStringWithShadow("Gained " + skill + " exp : "
				+ (skills.getCurrentSkillExp(stat) - startExp), X + 10,
				Y += 15, g);
		drawStringWithShadow("Exp/hour : " + xpPHour, X + 10, Y += 15, g);
		drawStringWithShadow("Activity : " + status, X + 10, Y += 15, g);
		// }
	}

	@Override
	public void serverMessageRecieved(ServerMessageEvent e) {
		String m = e.getMessage();

		if (m.contains("run out") || m.contains("resistance")
				|| m.contains("dragonfire")) {
			drinkAFire = true;
		}
	}

	// METHODS MADE OR FOUND BY MOUCHICC:
	public void drawStringWithShadow(final String text, final int x,
			final int y, final Graphics g) {

		final Color col = g.getColor();
		g.setColor(new Color(0, 0, 0));
		g.drawString(text, x + 1, y + 1);
		g.setColor(col);
		g.drawString(text, x, y);
	}

	// Method made by Jacmob
	public boolean castAlchSpell() {
		final int GambleInt = random(1, 200);

		if (GambleInt == 7) {
			moveMouse(520 + random(0, 230), 130 + random(0, 100));
			wait(random(100, 800));
		}
		if (GambleInt <= 3) {
			openTab(Constants.TAB_MAGIC);
			if (castSpell(Constants.SPELL_HIGH_LEVEL_ALCHEMY)) {
				return true;
			}
		} else if (GambleInt == 4) {
			openTab(Constants.TAB_MAGIC);
			wait(random(100, 200));
			if (castSpell(Constants.SPELL_HIGH_LEVEL_ALCHEMY)) {
				return true;
			}
		} else if (GambleInt == 5) {
			openTab(Constants.TAB_MAGIC);
			wait(random(50, 150));
			wait(random(50, 150));
			if (castSpell(Constants.SPELL_HIGH_LEVEL_ALCHEMY)) {
				return true;
			}
		} else if (GambleInt == 6 && getCurrentTab() != Constants.TAB_STATS) {
			wait(random(1, 20));
			moveMouse(567 + random(0, 25), 393 + random(0, 14));
			wait(random(1100, 1800));
			openTab(Constants.TAB_MAGIC);
			if (castSpell(Constants.SPELL_HIGH_LEVEL_ALCHEMY)) {
				return true;
			}
		} else {
			openTab(Constants.TAB_MAGIC);
			wait(random(150, 300));
			if (castSpell(Constants.SPELL_HIGH_LEVEL_ALCHEMY)) {
				return true;
			}
		}
		wait(random(20, 85));
		return false;
	}

	private String getChatMessage() {
		if (RSInterface.getInterface(137) != null) {
			return RSInterface.getInterface(137).getText();
		}
		return null;
	}

	@SuppressWarnings("unused")
	private boolean chatContains(String contains) {
		if (RSInterface.getInterface(137) != null) {
			String chat = getChatMessage();
			if (chat.contains(contains)) {
				return true;
			}
		}
		return false;
	}

	// Method for picking up an item
	public boolean pick(int[] ids, String act) {
		try {
			for (int i = 0; i < ids.length; i++) {
				while ((tile = getGroundItemByID(ids[i])) != null) {
					Point p = tileToMinimap(tile);

					if (tileOnScreen(tile)) {
						item = Integer.toString(ids[i]);
						if (atTile(tile, act)) {
							while (getMyPlayer().isMoving()) {
								wait(random(200, 400));
							}
							return true;
						}
					} else if (!tileOnScreen(tile) && tileOnMap(tile)) {
						if (p.x == -1 || p.y == -1) {
							return false;
						}
						moveMouse(p, 2, 2);
						clickMouse(p, true);
						while (getMyPlayer().isMoving()) {
							wait(random(200, 400));
						}
						return true;
					} else if (!tileOnScreen(tile) && !tileOnMap(tile)
							&& items == profitItems) {
						if (walkPathMM(randomizePath(
								fixPath(generateProperPath(tile)), 2, 2), 17)) {
							while (getMyPlayer().isMoving()) {
								wait(random(200, 400));
							}
							return true;
						}
					}
				}
			}
		} catch (Exception e) {
		}

		return false;
	}

	// Method to click an item in the Inventory with a boolean
	private boolean clickInventoryItem(int itemID, boolean click) {
		if (getCurrentTab() != TAB_INVENTORY
				&& !RSInterface.getInterface(INTERFACE_BANK).isValid()
				&& !RSInterface.getInterface(INTERFACE_STORE).isValid()) {
			openTab(TAB_INVENTORY);
		}
		int[] items = getInventoryArray();
		java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0)
			return false;
		int idx = possible.get(random(0, possible.size()));
		Point t = getInventoryItemPoint(idx);
		clickMouse(t, 5, 5, click);
		return true;
	}

	// Walk smart method -> onScreen || onMinimap
	public boolean WalkSmart(RSTile t2) {
		try {
			RSTile t = new RSTile(t2.getX() + random(-1, 1), t2.getY()
					+ random(-1, 1));
			Point p = tileToMinimap(t);
			if (tileOnScreen(t)) {
				if (atTile(t, "Walk Here")) {
					while (getMyPlayer().isMoving()) {
						wait(random(200, 400));
					}
					return true;
				}
			} else {
				if (p.x == -1 || p.y == -1) {
					return false;
				}
				moveMouse(p, 2, 2);
				clickMouse(p, true);
				while (getMyPlayer().isMoving()) {
					wait(random(200, 400));
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	// IDtoName for int
	public String IDtoName(int id) {
		try {
			URL url = new URL("http://itemdb-rs.runescape.com/viewitem.ws?obj="
					+ id);
			final BufferedReader reader = new BufferedReader(
					new InputStreamReader(url.openStream()));

			String line;
			// <div class="subsectionHeader">
			// <font color="RoyalBlue"><font size="6">BTekksCrabs
			int i = 0;
			while ((line = reader.readLine()) != null) {
				if (line.equals("<div class=" + '"' + "subsectionHeader" + '"'
						+ ">")) {
					i++;
					continue;
				}
				if (i == 1) {
					return line;
				}
			}
		} catch (Exception e) {

		}
		return null;
	}

	// IDtoName for int[]
	public String[] IDtoName(int[] ids) {
		ArrayList<String> s = new ArrayList<String>();
		for (int r = 0; r < ids.length; r++) {
			try {
				URL url = new URL(
						"http://itemdb-rs.runescape.com/viewitem.ws?obj="
								+ ids[r]);
				final BufferedReader reader = new BufferedReader(
						new InputStreamReader(url.openStream()));

				String line;
				int i = 0;
				while ((line = reader.readLine()) != null) {
					if (line.equals("<div class=" + '"' + "subsectionHeader"
							+ '"' + ">")) {
						i++;
						continue;
					}
					if (i == 1) {
						s.add(line);
						break;
					}
				}
			} catch (Exception e) {

			}
		}
		return s.toArray(new String[s.size()]);
	}

	// Clicks a NPC by Ruski
	public boolean clickNPC(RSNPC npc, String action) {
		if (npc == null) {
			return false;
		}
		RSTile tile = npc.getLocation();
		if (!tile.isValid()) {
			return false;
		}

		try {
			Point screenLoc = npc.getScreenLocation();
			if (distanceTo(tile) > 6 || !pointOnScreen(screenLoc)) {
				turnToTile(tile);
			}
			for (int i = 0; i < 12; i++) {
				screenLoc = npc.getScreenLocation();
				if (!npc.isValid() || !pointOnScreen(screenLoc)) {
					return false;
				}
				moveMouse(screenLoc, 5, 5);
				if (getMenuItems().get(0).toLowerCase().contains(
						npc.getName().toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
			}
			List<String> menuItems = getMenuItems();
			if (menuItems.isEmpty()) {
				return false;
			}
			for (int a = 0; a < menuItems.size(); a++) {
				if (menuItems.get(a).toLowerCase().contains(
						npc.getName().toLowerCase())) {
					if (menuItems.get(0).toLowerCase().contains(
							action.toLowerCase())) {
						clickMouse(true);
						return true;
					} else {
						clickMouse(false);
						return atMenu(action);
					}
				}
			}
		} catch (Exception e) {
			System.out.print("m.clickNPC(RSNPC, String) error: " + e);
			return false;
		}
		return false;
	}

	// Method for clicking an inventoryItem
	public boolean clickInventoryItem(int itemID, String option) {
		if (getCurrentTab() != TAB_INVENTORY) {
			openTab(TAB_INVENTORY);
		}
		int[] items = getInventoryArray();
		java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0) {
			return false;
		}
		int idx = possible.get(random(0, possible.size()));
		Point t = getInventoryItemPoint(idx);
		moveMouse(t, 5, 5);
		long waitTime = System.currentTimeMillis() + random(50, 250);
		boolean found = false;
		while (!found && System.currentTimeMillis() < waitTime) {
			wait(15);
			if ((getMenuItems()).get(0).toLowerCase().contains(
					option.toLowerCase())) {
				found = true;
			}
		}
		if (found) {
			clickMouse(true);
			wait(random(150, 250));
			return true;
		}
		clickMouse(false);
		wait(random(150, 250));
		return atMenu(option);
	}

	// WORLD SWITCHER BY BOOL
	static class WorldSwitcher {
		public static World[] worlds = null;
		private final static int WORLD_INTERFACE = 744;
		private final static int COMPONENTS = 26;
		static Methods m = new Methods();

		public static RSInterfaceComponent[] getComponents() {
			return RSInterface.getChildInterface(WORLD_INTERFACE, COMPONENTS)
					.getComponents();
		}

		public static void changeWorld(int worldnumber) {
			if (worlds == null)
				loadWorlds();
			Rectangle theRect = new Rectangle(79, 148, 608, 229);
			Rectangle a = null;
			World world = null;
			for (World w : worlds) {
				if (w.getWorldNumber() == worldnumber) {
					world = w;
					break;
				}
			}
			while (!theRect.contains((a = world.getArea()))) {
				if (!theRect.contains(m.getMouseLocation())) {
					m.moveMouse(theRect.x
							+ Bot.getInputManager().random(0,
									world.getArea().width), theRect.y
							+ Bot.getInputManager().random(0,
									world.getArea().height));
				}
				if (new Point(a.x, a.y).distance(new Point(100, 132)) < new Point(
						a.x, a.y).distance(new Point(104, 455))) {
					scroll(false);
					try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} else {
					scroll(true);
					try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			m.clickMouse(world.getArea().x
					+ Bot.getInputManager().random(0, world.getArea().width),
					world.getArea().y
							+ Bot.getInputManager().random(0,
									world.getArea().height), true);
		}

		public static void scroll(boolean up) {
			int x = m.getMouseLocation().x;
			int y = m.getMouseLocation().y;
			MouseWheelEvent event = new MouseWheelEvent(((Applet) Bot
					.getClient()), MouseEvent.MOUSE_WHEEL, System
					.currentTimeMillis(), 0, x, y, 0, false,
					MouseWheelEvent.WHEEL_UNIT_SCROLL, 3, (up ? 1 : -1));
			Bot.getClient().getMouseWheel()._mouseWheelMoved(event);
		}

		public static void loadWorlds() {
			ArrayList<World> result = new ArrayList<World>();
			RSInterfaceComponent[] coms = getComponents();
			int index = 0;
			for (RSInterfaceComponent i : coms) {
				index++;
				if (i != null && i.isValid()) {
					if (i.getText() != null && !i.getText().contains("Bounty")
							&& i.getText().contains("World")
							&& !coms[index].getText().isEmpty()) {
						int pop = coms[index].getText().equals("FULL")
								|| coms[index].getText().equals("OFFLINE") ? 2000
								: Integer
										.parseInt(coms[index].getText().trim());
						boolean mem = coms[index + 7].getText().contains(
								"Members");
						String worldNam = i.getText();
						int worldNum = Integer.parseInt(worldNam.replace(
								"World ", ""));
						result.add(new World(i.getText(), worldNum, pop, mem,
								index - 1));
					}
				}
			}
			worlds = result.toArray(new World[result.size()]);
		}

		static class World {
			private String worldName;
			private int worldNumber = -1;
			private int index = 0;
			private int worldPopulation = -1;
			private boolean members = false;
			private final int WORLD_INTERFACE = 744;
			private final int COMPONENTS = 26;

			public World(String worldName, int worldNumber,
					int worldPopulation, boolean members, int i) {
				this.index = i;
				this.worldName = worldName;
				this.worldNumber = worldNumber;
				this.worldPopulation = worldPopulation;
				this.members = members;
			}

			public RSInterfaceComponent toInterface() {
				return getComponents()[index];
			}

			private RSInterfaceComponent[] getComponents() {
				return RSInterface.getChildInterface(WORLD_INTERFACE,
						COMPONENTS).getComponents();
			}

			public boolean isMembers() {
				return members;
			}

			public int getWorldNumber() {
				return worldNumber;
			}

			public String getWorldName() {
				return worldName;
			}

			public int getWorldPopulation() {
				return worldPopulation;
			}

			public Rectangle getArea() {
				RSInterfaceComponent com = toInterface();
				Rectangle r = com.getArea();
				r.y -= RSInterface.getChildInterface(WORLD_INTERFACE,
						COMPONENTS).getVerticalScrollBarPosition();
				r.width = 608;
				r.x = 79;
				return r;
			}
		}
	}
}
